// remote_config.c
#include "RemoteConfig.h"
#include "EspressifHTTPClient.cpp"

#define TAG "RemoteConfig"

#define PUI_DEVICE_VERSION_BODY "{\"deviceProfileVersion\":\"%s\"}"

/**
 * 获取当前设备版本号
 */
char *RemoteConfig::readDeviceVersion(void) {
	static char version[6] = "-1"; // 默认版本 0
	size_t len = sizeof(version);
	nvs_handle_t nvs;

	if (nvs_open("nvs", NVS_READONLY, &nvs) == ESP_OK) {
		esp_err_t err = nvs_get_str(nvs, "version", version, &len);
		nvs_close(nvs);
	}
	ESP_LOGI(TAG, "read device version %s", version);
	return version;
}

void RemoteConfig::wirteDeviceVersion(const char *version) {
	nvs_handle_t nvs;
	if (nvs_open("nvs", NVS_READWRITE, &nvs) == ESP_OK) {
		esp_err_t err = nvs_set_str(nvs, "version", version);
		if (err == ESP_OK) {
			ESP_LOGI(TAG, "save device version %s", version);
		} else {
			ESP_LOGE(TAG, "save device version %s fail %s", version,
					 esp_err_to_name(err));
		}
		nvs_close(nvs);
	}
}

void RemoteConfig::run(void *arg) {
	// 先测试最简单的操作
	Helper::generateDeviceId(imei);
	const TickType_t xDelay = pdMS_TO_TICKS(10000); // 1秒延迟

	// 拼接profileVersion接口URL，使用IMEI做设备标识
	char getProfileVersionUrl[256];
	snprintf(getProfileVersionUrl, sizeof(getProfileVersionUrl), GET_SERVICE_PROFILE_VERSION_URL, imei);
	// 获取远程参数
	char getProfileUrl[256];
	snprintf(getProfileUrl, sizeof(getProfileUrl), GET_DEVICE_VERSION_URI, imei, 0);
	// 提交设备参数版本
	char postVersionUrl[256];
	snprintf(postVersionUrl, sizeof(postVersionUrl), PUT_DEVICE_VERSION_URL, imei);

	m_http_client = new EspressifHTTPClient();
	m_http_client->connect(HOST, PORT);
	m_http_client->setHttpsEnabled(true);
	m_http_client->setCertificate(ROOT_CERT);

	while (1) {
		int status = m_http_client->get(getProfileVersionUrl);
		if (status == 200) {
			std::string response = m_http_client->getResponseBody();
			cJSON *root = cJSON_Parse(response.c_str());
			cJSON *ver_item = cJSON_GetObjectItem(root, "profileVersion");
			char *version = this->readDeviceVersion();
			// 对比版本号
			if (ver_item->valuestring != NULL && strcmp(version, ver_item->valuestring) != 0) {
				const char *newVersion = ver_item->valuestring;
				// 准备更新参数
				status = m_http_client->get(getProfileUrl);
				// 远程参数是否获取成功
				if (status == 200) {
					ESP_LOGI(TAG, "begin update device params ");
					std::string response = m_http_client->getResponseBody();
					write_profile(response.c_str());
					wirteDeviceVersion(newVersion);
					char post_data[64];
					snprintf(post_data, sizeof(post_data), PUI_DEVICE_VERSION_BODY, newVersion);
					status = m_http_client->post(postVersionUrl, "application/json", post_data);
					ESP_LOGI(TAG, "end update device params restart......");
					esp_restart();
				} else {
					ESP_LOGE(TAG, "get remote params err http status:%d", status);
				}
			}
			// 释放获取远程版本的内存
			cJSON_Delete(root);
		} else {
			ESP_LOGE(TAG, "get remote version err url:%s http status:%d", getProfileVersionUrl, status);
		}
		// 这里暂未请求第二个接口，任务延迟
		vTaskDelay(xDelay);
	}
}

/**
 * @brief 任务主循环，周期性执行HTTP请求
 *
 * 这个任务会每隔1秒请求一次profileVersion接口，然后根据返回做后续处理（示例中仅打印）
 */
void RemoteConfig::taskWrapper(void *arg) {
	RemoteConfig *self = static_cast<RemoteConfig *>(arg);
	self->run(arg);
}

/**
 * @brief 启动远程配置任务
 */
void RemoteConfig::monitorRemoteConfigBoot(void) {
	ESP_LOGI(TAG, "monitorRemoteConfigBoot beigin.....");
	xTaskCreate(&RemoteConfig::taskWrapper, "remote_config", 6144, this, 5, NULL);
}
